<?php
/*
# $Id: Object.php 10 2006-11-18 12:34:32Z James $
*/

class Object {

	/*
	# @property string $HASH
	# Stores the unique object hash for this object.
	*/
	public $HASH = NULL;

	/*
	# @property array $listeners
	# Holds all events listeners for this Object.
	# Array indicies are event names, eg. "onload", "onrender", etc. and each elenent is an array
	# of listeners each in the following format:
	#	object|NULL 'object'	=> A class instance (if the listener is a class method) or NULL (if the listener is a global function)
	#	string 'function'	=> Name of the class method or global function name
	#	array 'aguments'	=> Array of arguments to pass to the method/function on invocation
	*/
	private $listeners = array();

	/*
	# @method void __construct()
	#
	# Classes that inherit from this class must call parent::__construct()
	*/
	public function __construct() {

		// Store unique hash
		$this->HASH = spl_object_hash($this);
	}

	/*
	# @method void addEventListener( string $eventName, array|string $listener, array $arguments )
	# $eventName	= Name of the event to which the listener will be attached (all lowercase, prefixed with "on", eg. "onload")
	# $listener		= Class Instance and method (ie. array($instance, 'method-name')) or global function name (ie. 'function-name')
	# $arguments	= Arguments to be passed to the listener when the event is invoked.
	#
	# Adds a listener to the specified event. When the event is invoked the listener will be executed.
	*/
	public function addEventListener($eventName, $listener, $arguments=array()) {

		// Create an entry for $eventName in $this->events first
		if(!isset($this->listeners[$eventName])) {
			$this->listeners[$eventName] = array();
		}

		// Store the listener
		if(is_array($listener)) {
			$this->listeners[$eventName][] = array(
				'object'=>$listener[0],
				'function'=>$listener[1],
				'arguments'=>$arguments
			);
		}
		else {
			$this->listeners[$eventName][] = array(
				'object'=>NULL,
				'function'=>$listener,
				'arguments'=>$arguments
			);
		}
	}

	/*
	# @metho void removeEventListener( string $eventName, )
	*/
	function removeEventListener($eventName, $listener) {
	}

	/*
	# @method void invokeEvent( string $eventName )
	# $eventName	= Event name
	#
	# Executes all listeners registered to the specified event in the order they were added.
	*/
	public function invokeEvent($eventName) {

		// Ignore non-existent events
		if(!isset($this->listeners[$eventName])) {
			SystemLog::add("Event \"{$eventName}\" does not exist for this object.", SystemLog::NOTICE);
			return NULL;
		}

		// Cycle through all events listeners
		foreach($this->listeners[$eventName] as $listener) {

			// Execute global function
			if($listener['object']===NULL) {
				$listener['function']($listener['arguments']);
			}

			// Execute static class method
			else if(is_string($listener['object'])) {
				call_user_func_array(array($listener['object'], $listener['function']), $listener['arguments']);
			}

			// Execute normal class method
			else {
				$listener['object']->{$listener['function']}($listener['arguments']);
			}
		}
	}
}
?>